{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "工作中，经常需要将Word文档中的表格粘贴到Excel文件中，以便汇总及分析。一个一个复制粘贴，非常不方便，还是Python自动化操作，省心省力。要求如下图所示，即将word中的所有表格，转存到excel文件的工作表里。\n",
    "![](images\\requirement.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "from docx import Document\n",
    "from openpyxl import Workbook\n",
    "\n",
    "#获取待处理的文件的路径\n",
    "path='word文件'  #文件所在文件夹\n",
    "files = [path+\"\\\\\"+i for i in os.listdir(path)] #获取文件夹下的文件名,并拼接完整路径\n",
    "\n",
    "for file in files:\n",
    "    doc = Document(file)\n",
    "\n",
    "    wb = Workbook()\n",
    "    wb.remove(wb.worksheets[0])#删除工作簿自带的工作表\n",
    "    for index, table in enumerate(doc.tables, start=1): #从1开始给表格编号\n",
    "        ws = wb.create_sheet(f\"Sheet{index}\")#创建新工作表，以\"Sheet\" + word中表格的编号命名\n",
    "        for i in range(len(table.rows)): #遍历word中表格的所有行\n",
    "            row_data = [] #储存表格中每行的数据\n",
    "            for j in range(len(table.columns)): #遍历word中表格的所有列\n",
    "                row_data.append(table.cell(i,j).text)\n",
    "            ws.append(row_data) #每取一行就写入数据到Excel表的行中\n",
    "            \n",
    "    wb.save(\"excel文件\\\\{}.xlsx\".format(file.split(\"\\\\\")[1].split(\".\")[0])) #保存excel文件"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "以上，先导入相关模块。`os`用于获取待处理word文件的路径；`docx`用于读取`word`文件；`openpyxl`用于操作`excel`文件。将所有word文件的路径存入列表`files`中。然后逐个通过`Document`打开，并使用`Workbook()`创建Excel工作簿，以接收来自于word文件中的数据。因为创建工作簿后，Excel会自动新建一个名为\"Sheet\"的空白表格，但我们想用自己命名的表格，所以使用`remove()`将自动新建的表删掉了。\n",
    "<br/>然后遍历`word`文件中的所有表格，并读取其中的数据。由于我们想让`Excel`工作簿中的表的序号与`Word`中的一致，所以使用`enmuerate`给`Word`中的表格进行编号，`start=1`表示从1开始，不然会默认从0开始。\n",
    "<br/>随后使用`wb.create_sheet`新建一个工作表，其表名就用字符串\"Sheet\"加上上面的编号。其中`f\"{}\"`是格式化字符串方法，从Python 3.6开始加入标准库，是一种更灵活好用的方法。如下有四种方式处理字符串，结果完全一样，不过第一种最好用，墙裂推荐。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'你好, Trump， 你的年龄是70岁.'"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "name = \"Trump\"\n",
    "age = 70\n",
    "f\"你好, {name}， 你的年龄是{age}岁.\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'你好, Trump， 你的年龄是70岁.'"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"你好, {}， 你的年龄是{}岁.\".format(name,age)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'你好, Trump， 你的年龄是70岁.'"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"你好, %s， 你的年龄是%s岁.\" % (name, age)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'你好, Trump， 你的年龄是70岁.'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"你好, \" +name +\"， 你的年龄是\" + str(age) + \"岁.\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "然后遍历word中表格的所有行和列，将每行的数据存入列表`row_data`，然后通过`append`方法马上增加到Excel表中最后一个数据下面。`append`方法可以将一个列表中的所有元素写入到excel表的一行，一个元素占一个单元格（如下图），够智能的吧？\n",
    "![](images\\append.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "处理完一个word文件，就保存一下数据。为了使保存的excel文件名与word文件名一致，使用了`file.split(\"\\\\\")[1].split(\".\")[0])`。其中`file`的内容如下。`file.split(\"\\\\\")[1]`就得到了'采购报告.docx'，`'采购报告.docx'.split(\".\")[0]`就得到了“采购报告”。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'word文件\\\\采购报告.docx'"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "file"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'采购报告.docx'"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "file.split(\"\\\\\")[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'采购报告'"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'采购报告.docx'.split(\".\")[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "结果图如下。word文件中有多少个表格，就会在excel文件中生成多少个sheet。而且，如果在word文件中有合并单元格，那到excel文件中，这些单元格会拆分，并填充相同的内容，更利于数据分析。当然，结果excel文件中的格式就不是那么好看了，需要手动调整一下。\n",
    "![](images\\\\result.png)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
